<?php
/**
 * 支付接口调测例子
 * ================================================================
 * index 进入口，方法中转
 * submitOrderInfo 提交订单信息
 * queryOrder 查询订单.
 *
 * ================================================================
 */

namespace app\api\service\payment\Unionpay;

class Request
{
    private $resHandler = null;
    private $reqHandler = null;
    private $pay = null;
    private $cfg = null;

    public function __construct($config)
    {
        $this->resHandler = new ClientResponseHandler();
        $this->reqHandler = new RequestHandler();
        $this->pay = new PayHttpClient();
        $this->cfg = new Config($config);
        $this->reqHandler->setGateUrl($this->cfg->C('url'));
        $sign_type = $this->cfg->C('sign_type');

        if ('MD5' == $sign_type) {
            $this->reqHandler->setKey($this->cfg->C('key'));
            $this->resHandler->setKey($this->cfg->C('key'));
            $this->reqHandler->setSignType($sign_type);
        } elseif ('RSA_1_1' == $sign_type || 'RSA_1_256' == $sign_type) {
            $this->reqHandler->setRSAKey($this->cfg->C('private_rsa_key'));
            $this->resHandler->setRSAKey($this->cfg->C('public_rsa_key'));
            $this->reqHandler->setSignType($sign_type);
        }
    }

    public function index()
    {
        $method = isset($_REQUEST['method']) ? $_REQUEST['method'] : 'submitOrderInfo';
        switch ($method) {
            case 'submitOrderInfo': //提交订单
                $this->submitOrderInfo($_POST, "");
                break;
            case 'queryOrder': //查询订单
                $this->queryOrder();
                break;
            case 'closeOrder': //关闭订单
                $this->closeOrder();
                break;
            case 'submitRefund': //提交退款
                $this->submitRefund();
                break;
            case 'queryRefund': //查询退款
                $this->queryRefund();
                break;
            case 'callback':
                $this->callback();
                break;
        }
    }

    /**
     * 提交订单信息.
     */
    public function submitOrderInfo($type, $params, $notifyUrl)
    {
        $this->reqHandler->setReqParams($params);
        // $this->reqHandler->setParameter('service','pay.weixin.native');//接口类型：pay.weixin.native  表示微信扫码
        $this->reqHandler->setParameter('service', "pay.{$type}.native"); //接口类型：pay.alipay.native  表示支付宝扫码
        // $this->reqHandler->setParameter('service','pay.jdpay.native');//接口类型：pay.jdpay.native   表示京东钱包扫码
        // $this->reqHandler->setParameter('service','pay.unionpay.native');//接口类型：pay.unionpay.native   表示银联钱包扫码
        $this->reqHandler->setParameter('mch_id', $this->cfg->C('mchId')); //必填项，商户号，由威富通分配
        $this->reqHandler->setParameter('version', $this->cfg->C('version'));
        $this->reqHandler->setParameter('sign_type', $this->cfg->C('sign_type'));
        // $this->reqHandler->setParameter('limit_credit_pay', '1');

        //通知地址，必填项，接收威富通通知的URL，需给绝对路径，255字符内格式如:http://wap.tenpay.com/tenpay.asp
        //$notify_url = 'http://'.$_SERVER['HTTP_HOST'];
        $this->reqHandler->setParameter('notify_url', $notifyUrl);
        $this->reqHandler->setParameter('nonce_str', mt_rand(time(), time() + rand())); //随机字符串，必填项，不长于 32 位
        $this->reqHandler->createSign(); //创建签名

        $data = Utils::toXml($this->reqHandler->getAllParameters());

        $this->pay->setReqContent($this->reqHandler->getGateURL(), $data);
        if ($this->pay->call()) {
            $this->resHandler->setContent($this->pay->getResContent());
            $this->resHandler->setKey($this->reqHandler->getKey());
            if ($this->resHandler->isTenpaySign()) {
                //当返回状态与业务结果都为0时才返回支付二维码，其它结果请查看接口文档
                if (0 == $this->resHandler->getParameter('status') && 0 == $this->resHandler->getParameter('result_code')) {
                    return array(
                        'code_img_url' => $this->resHandler->getParameter('code_img_url'),
                        'code_url' => $this->resHandler->getParameter('code_url'),
                        'code_status' => $this->resHandler->getParameter('code_status'),
                        'type' => $this->reqHandler->getParameter('service'),
                    );
                } else {
                    throw new \Exception($this->resHandler->getParameter('err_msg'), $this->resHandler->getParameter('err_code'));
                    // echo json_encode(array('status'=>500,'msg'=>'Error Code:'.$this->resHandler->getParameter('err_code').' Error Message:'.$this->resHandler->getParameter('err_msg')));
                    // exit();
                }
            }

            throw new \Exception($this->resHandler->getParameter('message'), $this->resHandler->getParameter('status'));
            // echo json_encode(array('status'=>500,'msg'=>'Error Code:'.$this->resHandler->getParameter('status').' Error Message:'.$this->resHandler->getParameter('message')));
            //exit();
        } else {
            throw new \Exception($this->pay->getErrInfo(), $this->pay->getResponseCode());
            // echo json_encode(array('status'=>500,'msg'=>'Response Code:'.$this->pay->getResponseCode().' Error Info:'.$this->pay->getErrInfo()));
            //exit();
        }
    }

    /**
     * 查询订单.
     */
    public function queryOrder()
    {
        $this->reqHandler->setReqParams($_POST, array('method'));
        $reqParam = $this->reqHandler->getAllParameters();
        if (empty($reqParam['transaction_id']) && empty($reqParam['out_trade_no'])) {
            echo json_encode(array(
                'status' => 500,
                'msg' => '请输入商户订单号,威富通订单号!',
            ));
            exit();
        }
        $this->reqHandler->setParameter('version', $this->cfg->C('version'));
        $this->reqHandler->setParameter('service', 'unified.trade.query'); //接口类型：unified.trade.query
        $this->reqHandler->setParameter('mch_id', $this->cfg->C('mchId')); //必填项，商户号，由威富通分配
        $this->reqHandler->setParameter('nonce_str', mt_rand(time(), time() + rand())); //随机字符串，必填项，不长于 32 位
        $this->reqHandler->setParameter('sign_type', $this->cfg->C('sign_type'));
        $this->reqHandler->createSign(); //创建签名
        $data = Utils::toXml($this->reqHandler->getAllParameters());

        $this->pay->setReqContent($this->reqHandler->getGateURL(), $data);
        if ($this->pay->call()) {
            $this->resHandler->setContent($this->pay->getResContent());
            $this->resHandler->setKey($this->reqHandler->getKey());
            if ($this->resHandler->isTenpaySign()) {
                $res = $this->resHandler->getAllParameters();
                Utils::dataRecodes('查询订单', $res);
                //支付成功会输出更多参数，详情请查看文档中的7.1.4返回结果
                echo json_encode(array('status' => 200, 'msg' => '查询订单成功，请查看result.txt文件！', 'data' => $res));
                exit();
            }
            echo json_encode(array('status' => 500, 'msg' => 'Error Code:' . $this->resHandler->getParameter('status') . ' Error Message:' . $this->resHandler->getParameter('message')));
        } else {
            echo json_encode(array('status' => 500, 'msg' => 'Response Code:' . $this->pay->getResponseCode() . ' Error Info:' . $this->pay->getErrInfo()));
        }
    }

    /* 关闭订单*/

    public function closeOrder()
    {
        $this->reqHandler->setReqParams($_POST, array('method'));
        $reqParam = $this->reqHandler->getAllParameters();
        if (empty($reqParam['out_trade_no'])) {
            echo json_encode(array(
                'status' => 500,
                'msg' => '请输入商户订单号!',
            ));
            exit();
        }
        $this->reqHandler->setParameter('version', $this->cfg->C('version'));
        $this->reqHandler->setParameter('service', 'unified.trade.close'); //接口类型：unified.trade.close
        $this->reqHandler->setParameter('mch_id', $this->cfg->C('mchId')); //必填项，商户号，由威富通分配
        $this->reqHandler->setParameter('nonce_str', mt_rand(time(), time() + rand())); //随机字符串，必填项，不长于 32 位
        $this->reqHandler->setParameter('sign_type', $this->cfg->C('sign_type'));
        $this->reqHandler->createSign(); //创建签名
        $data = Utils::toXml($this->reqHandler->getAllParameters());

        $this->pay->setReqContent($this->reqHandler->getGateURL(), $data);
        if ($this->pay->call()) {
            $this->resHandler->setContent($this->pay->getResContent());
            $this->resHandler->setKey($this->reqHandler->getKey());
            if ($this->resHandler->isTenpaySign()) {
                //当返回状态与业务结果都为0时才返回支付二维码，其它结果请查看接口文档
                if (0 == $this->resHandler->getParameter('status') && 0 == $this->resHandler->getParameter('result_code')) {
                    /*$res = array('transaction_id'=>$this->resHandler->getParameter('transaction_id'),
                                 'out_trade_no'=>$this->resHandler->getParameter('out_trade_no'),
                                 'out_refund_no'=>$this->resHandler->getParameter('out_refund_no'),
                                 'refund_id'=>$this->resHandler->getParameter('refund_id'),
                                 'refund_channel'=>$this->resHandler->getParameter('refund_channel'),
                                 'refund_fee'=>$this->resHandler->getParameter('refund_fee'),
                                 'coupon_refund_fee'=>$this->resHandler->getParameter('coupon_refund_fee'));*/
                    $res = $this->resHandler->getAllParameters();
                    Utils::dataRecodes('关闭订单', $res);
                    echo json_encode(array('status' => 200, 'msg' => '关闭订单成功,请查看result.txt文件！', 'data' => $res));
                    exit();
                } else {
                    echo json_encode(array('status' => 500, 'msg' => 'Error Code:' . $this->resHandler->getParameter('err_code') . ' Error Message:' . $this->resHandler->getParameter('err_msg')));
                    exit();
                }
            }
            echo json_encode(array('status' => 500, 'msg' => 'Error Code:' . $this->resHandler->getParameter('status') . ' Error Message:' . $this->resHandler->getParameter('message')));
        } else {
            echo json_encode(array('status' => 500, 'msg' => 'Response Code:' . $this->pay->getResponseCode() . ' Error Info:' . $this->pay->getErrInfo()));
        }
    }

    /**
     * 提交退款.
     */
    public function submitRefund()
    {
        $this->reqHandler->setReqParams($_POST, array('method'));
        $reqParam = $this->reqHandler->getAllParameters();
        if (empty($reqParam['transaction_id']) && empty($reqParam['out_trade_no'])) {
            echo json_encode(array(
                'status' => 500,
                'msg' => '请输入商户订单号或威富通订单号!',
            ));
            exit();
        }
        $this->reqHandler->setParameter('version', $this->cfg->C('version'));
        $this->reqHandler->setParameter('service', 'unified.trade.refund'); //接口类型：unified.trade.refund
        $this->reqHandler->setParameter('mch_id', $this->cfg->C('mchId')); //必填项，商户号，由威富通分配
        $this->reqHandler->setParameter('nonce_str', mt_rand(time(), time() + rand())); //随机字符串，必填项，不长于 32 位
        $this->reqHandler->setParameter('op_user_id', $this->cfg->C('mchId')); //必填项，操作员帐号,默认为商户号
        $this->reqHandler->setParameter('sign_type', $this->cfg->C('sign_type'));

        $this->reqHandler->createSign(); //创建签名
        $data = Utils::toXml($this->reqHandler->getAllParameters()); //将提交参数转为xml，目前接口参数也只支持XML方式

        $this->pay->setReqContent($this->reqHandler->getGateURL(), $data);
        if ($this->pay->call()) {
            $this->resHandler->setContent($this->pay->getResContent());
            $this->resHandler->setKey($this->reqHandler->getKey());
            if ($this->resHandler->isTenpaySign()) {
                //当返回状态与业务结果都为0时才返回支付二维码，其它结果请查看接口文档
                if (0 == $this->resHandler->getParameter('status') && 0 == $this->resHandler->getParameter('result_code')) {
                    /*$res = array('transaction_id'=>$this->resHandler->getParameter('transaction_id'),
                                 'out_trade_no'=>$this->resHandler->getParameter('out_trade_no'),
                                 'out_refund_no'=>$this->resHandler->getParameter('out_refund_no'),
                                 'refund_id'=>$this->resHandler->getParameter('refund_id'),
                                 'refund_channel'=>$this->resHandler->getParameter('refund_channel'),
                                 'refund_fee'=>$this->resHandler->getParameter('refund_fee'),
                                 'coupon_refund_fee'=>$this->resHandler->getParameter('coupon_refund_fee'));*/
                    $res = $this->resHandler->getAllParameters();
                    Utils::dataRecodes('提交退款', $res);
                    echo json_encode(array('status' => 200, 'msg' => '退款成功,请查看result.txt文件！', 'data' => $res));
                    exit();
                } else {
                    echo json_encode(array('status' => 500, 'msg' => 'Error Code:' . $this->resHandler->getParameter('err_code') . ' Error Message:' . $this->resHandler->getParameter('err_msg')));
                    exit();
                }
            }
            echo json_encode(array('status' => 500, 'msg' => 'Error Code:' . $this->resHandler->getParameter('status') . ' Error Message:' . $this->resHandler->getParameter('message')));
        } else {
            echo json_encode(array('status' => 500, 'msg' => 'Response Code:' . $this->pay->getResponseCode() . ' Error Info:' . $this->pay->getErrInfo()));
        }
    }

    /**
     * 查询退款.
     */
    public function queryRefund()
    {
        $this->reqHandler->setReqParams($_POST, array('method'));
        if (0 === count($this->reqHandler->getAllParameters())) {
            echo json_encode(array(
                'status' => 500,
                'msg' => '请输入商户订单号,威富通订单号,商户退款单号,威富通退款单号!',
            ));
            exit();
        }
        $this->reqHandler->setParameter('version', $this->cfg->C('version'));
        $this->reqHandler->setParameter('service', 'unified.trade.refundquery'); //接口类型：unified.trade.refundquery
        $this->reqHandler->setParameter('mch_id', $this->cfg->C('mchId')); //必填项，商户号，由威富通分配
        $this->reqHandler->setParameter('nonce_str', mt_rand(time(), time() + rand())); //随机字符串，必填项，不长于 32 位
        $this->reqHandler->setParameter('sign_type', $this->cfg->C('sign_type'));

        $this->reqHandler->createSign(); //创建签名
        $data = Utils::toXml($this->reqHandler->getAllParameters()); //将提交参数转为xml，目前接口参数也只支持XML方式

        $this->pay->setReqContent($this->reqHandler->getGateURL(), $data); //设置请求地址与请求参数
        if ($this->pay->call()) {
            $this->resHandler->setContent($this->pay->getResContent());
            $this->resHandler->setKey($this->reqHandler->getKey());
            if ($this->resHandler->isTenpaySign()) {
                //当返回状态与业务结果都为0时才返回支付二维码，其它结果请查看接口文档
                if (0 == $this->resHandler->getParameter('status') && 0 == $this->resHandler->getParameter('result_code')) {
                    /*$res = array('transaction_id'=>$this->resHandler->getParameter('transaction_id'),
                                  'out_trade_no'=>$this->resHandler->getParameter('out_trade_no'),
                                  'refund_count'=>$this->resHandler->getParameter('refund_count'));
                    for($i=0; $i<$res['refund_count']; $i++){
                        $res['out_refund_no_'.$i] = $this->resHandler->getParameter('out_refund_no_'.$i);
                        $res['refund_id_'.$i] = $this->resHandler->getParameter('refund_id_'.$i);
                        $res['refund_channel_'.$i] = $this->resHandler->getParameter('refund_channel_'.$i);
                        $res['refund_fee_'.$i] = $this->resHandler->getParameter('refund_fee_'.$i);
                        $res['coupon_refund_fee_'.$i] = $this->resHandler->getParameter('coupon_refund_fee_'.$i);
                        $res['refund_status_'.$i] = $this->resHandler->getParameter('refund_status_'.$i);
                    }*/
                    $res = $this->resHandler->getAllParameters();
                    Utils::dataRecodes('查询退款', $res);
                    echo json_encode(array('status' => 200, 'msg' => '查询成功,请查看result.txt文件！', 'data' => $res));
                    exit();
                } else {
                    echo json_encode(array('status' => 500, 'msg' => 'Error Code:' . $this->resHandler->getParameter('err_code')));
                    exit();
                }
            }
            echo json_encode(array('status' => 500, 'msg' => $this->resHandler->getContent()));
        } else {
            echo json_encode(array('status' => 500, 'msg' => 'Response Code:' . $this->pay->getResponseCode() . ' Error Info:' . $this->pay->getErrInfo()));
        }
    }

    /**
     * 提供给威富通的回调方法.
     */
    public function callback()
    {
        $xml = file_get_contents('php://input');
//         $xml = <<<XML
// <xml><attach><![CDATA[扩展字段]]></attach>
// <bank_type><![CDATA[ALIPAYACCOUNT]]></bank_type>
// <charset><![CDATA[UTF-8]]></charset>
// <fee_type><![CDATA[CNY]]></fee_type>
// <invoice_amount><![CDATA[100]]></invoice_amount>
// <mch_id><![CDATA[7551000001]]></mch_id>
// <nonce_str><![CDATA[1560933015499]]></nonce_str>
// <openid><![CDATA[2088002003181694]]></openid>
// <out_trade_no><![CDATA[190619162925867]]></out_trade_no>
// <out_transaction_id><![CDATA[2019061922001481690595140213]]></out_transaction_id>
// <pay_result><![CDATA[0]]></pay_result>
// <result_code><![CDATA[0]]></result_code>
// <sign><![CDATA[5B6C536DC5230B9B4D0F50EEF13C64B3]]></sign>
// <sign_type><![CDATA[MD5]]></sign_type>
// <status><![CDATA[0]]></status>
// <time_end><![CDATA[20190619163014]]></time_end>
// <total_fee><![CDATA[100]]></total_fee>
// <trade_type><![CDATA[pay.alipay.native]]></trade_type>
// <transaction_id><![CDATA[7551000001201906193299399214]]></transaction_id>
// <version><![CDATA[2.0]]></version>
// </xml>
// XML;
        //$res = Utils::parseXML($xml);
        $this->resHandler->setContent($xml);
        //var_dump($this->resHandler->setContent($xml));
        $this->resHandler->setKey($this->cfg->C('key'));
        if ($this->resHandler->isTenpaySign()) {
            if (0 == $this->resHandler->getParameter('status') && 0 == $this->resHandler->getParameter('result_code')) {
                //echo $this->resHandler->getParameter('status');
                // 11;
                //更改订单状态
                // Utils::dataRecodes('接口回调收到通知参数', $this->resHandler->getAllParameters());
                return $this->resHandler->getAllParameters();
                // echo 'success';
                // exit();
            }
        }

        return false;
    }
}
